<?php
chdir("../");
require './MySQLAccess/MySQLConnection.php';

require './config.inc.php';
require './global.inc.php';

function getTypeFromDBType($DBType) {
  if (strpos($DBType, "(") === false) {
    $clean = $DBType;
  }
  else {    
    $clean = substr($DBType, 0, strpos($DBType, "(")-strlen($DBType));
  }

  switch ($clean) {
    case "int":
    case "smallint":
    case "timestamp": return "int"; break;
    case "varchar":
    case "char":
    case "blob":
    case "text": return "string";break;

    default: return "unknown";
      break;
  }
  //return $clean;
}

$tables = array();

try {
  $db = DBConnection($DBType);

  $result = $db->prepare("SHOW TABLES")->ExecuteQuery();
  while ($result->next()) {
    $tables[] = $result->Tables_in_bp;
  }




foreach($tables as $table){
  $str = "";
  $fields = array();
  $types = array();

  $query = 'select column_name, column_comment, column_type from information_schema.columns where table_name like :1';
  $stmt = $db->prepare($query);
  $stmt->Parameters->add($table);
  $result = $stmt->ExecuteQuery();
  while ($result->next()) {
    $fields[$result->column_name] = $result->column_comment;
    $types[] = getTypeFromDBType($result->column_type);
  }

  $i = 0;
  foreach ($fields as $key => $field) {
     $str .= "/**\n  * ".$field."\n  *\n  * @access private\n  * @var ".$types[$i++]."\n  */\n";
     $str .= "private \$_".$key.";\n\n";
  }

  $str .= "\n";

  $i = 0;
  foreach ($fields as $key => $field) {
    $str .= "/**\n  * Original ".$key."\n  *\n  * @access private\n  * @var ".$types[$i++]."\n  */\n";
    $str .= "private \$_".$key."Old;\n\n";
  }
  

  $str .= <<<EOT
/**
 * Handle to database connection
 *
 * @var DBConnection
 */
private \$DB;
  
public function __construct(\$id = null) {
  if(\$id === null) return;
EOT;
/*
  $str .= "\npublic function __construct (";
  $bool = false;
  foreach ($fields as $key => $field) {
    if($bool) $str .= ", "; else $bool = !$bool;
    $str .= "\$_".$key;
  }
  $str .= ") { \n";

  foreach ($fields as $key => $field) {
    $str .= '  $this->_'.$key.' = $'.$key.";\n";
  }

  $str .= "\n";

  foreach ($fields as $key => $field) {
    $str .= '  $this->_'.$key.'Old = $'.$key.";\n";
  }
*/
  //$str .= "\n  \$DB = DBConnection(\$DBType);\n";
  $str .= "\n\n";

  $table = ucfirst($table);
  $table[1] = strtoupper($table[1]);
  $file = fopen("./ORM/$table.php", "w");
  fwrite($file, "<?php\n\n");
  fwrite($file, "class $table {\n\n");
  fwrite($file, $str);

/*
  $str = "public static function getById(\$id) {\n";
  */
  $str = "  try {\n    \$this->DB = DBConnection(\$DBType);\n    \$query = \"SELECT ";
  
  $bool = false;
  foreach ($fields as $key => $field) {
    if($bool) $str .= ", "; else $bool = !$bool;
    $str .= $key;
  }

  $idName = array_keys($fields);
  $idName = $idName[0];
  
  $str .= " FROM $table WHERE $idName = :1\";\n";
  $str .= "    \$stmt = \$this->DB->prepare(\$query);\n    \$stmt->Parameters->add(\$id);\n    \$result = \$stmt->ExecuteQuery();";

  $str .= "\n    while (\$result->next()) {\n";
  //$str .= "      \$return = new $table(";
  $bool = false;
  foreach ($fields as $key => $field) {
    //if($bool) $str .= ", "; else $bool = !$bool;
    $str .= "      \$this->_$key = \$this->_{$key}Old = \$result->_".$key.";\n";
  }
  $str .= "\n    }\n  } catch (DBException \$ex) {\n    echo \$ex->getMessage();\n  }";

  $str .= "\n\n  if (\$return->id === null) return false;";

  $str .= "\n}\n\n";

  fwrite($file, $str);

$str = <<<EOT
public function  __get(\$name) {
  switch (\$name) {\n
EOT;
foreach ($fields as $key => $field) {
  $str .= "    case '$key': return \$this->_$key; break;\n";
}
$str .= <<<EOT
    default: return false; break;
  }
}


EOT;

fwrite($file, $str);

$str = <<<EOT
public function  __set(\$name, \$value) {
  switch (\$name) {\n
EOT;
foreach ($fields as $key => $field) {
  $str .= "    case '$key': \$this->_$key = \$value; break;\n";
}
$str .= <<<EOT
    default: return false; break;
  }
}


EOT;

fwrite($file, $str);

  $str = <<<EOT
  public function insert() {
    if (\$this->_$idName != null) throw new Exception("Can\'t insert record. ID is specified.");

    try {
      \$query = "INSERT INTO '.$table.' (
EOT;
   
  $bool = false;
  foreach ($fields as $key => $field) {
    if($bool) $str .= ", "; else $bool = !$bool;
    $str .= $key;
  }
  $str .= ') VALUES (';

  $count = count($fields);
  for($i = 1; $i <= $count; $i++) {
    if ($i == $count) $str .= ":$i";
    else $str .= ":$i, ";
  }
  $str .= ')";'."\n";
  
  $str .= '      $stmt = $this->DB->prepare($query);'."\n";

  foreach ($fields as $key => $field) {
    $str .= '      $stmt->Parameters->add($this->_'.$key.');'."\n";
  }
  
  $str .= <<<EOT
      \$stmt->ExecuteNonQuery();

      list(\$this->$idName) = \$this->DB->prepare("select last_inserted_id()")->ExecuteQuery->fetch_row();
    } catch (DBException \$ex) {
      echo \$ex->getMessage();
    }
  }
  
EOT;
  fwrite($file, $str);


  $str = <<<EOT

public function delete() {
  if (!\$this->_$idName) throw new Exception("Can't delete unknown record");
  try {
    \$query = "DELETE FROM table WHERE $idName = :1";
    \$stmt = \$this->DB->prepare(\$query);
    \$stmt->Parameters->add(\$this->_$idName);
    \$stmt->ExecuteNonQuery();
  } catch (DBException \$ex) {
    echo \$ex->getMessage();
  }
}\n

EOT;

  fwrite($file, $str);

  $str = <<<EOT
public function update() {
  if (\$this->_$idName == null) throw new Exception("Can\'t update unknown record.");
 
  \$updateStr = null;\n  \$i = 1;\n\n
EOT;
  $i=0;
  foreach ($fields as $key => $field) {    
    $str .= <<<EOT
  if (\$this->_$key != \$this->_{$key}Old) {
    if(\$updateStr != null) \$updateStr .= ", ";
    \$updateStr .= "$key = :\$i";
    \$i++;
  }\n\n
EOT;
  }

  $str .= <<<EOT
  try {
    \$query = "UPDATE $table SET \$updateStr WHERE $idName = \$this->_$idName";
    \$stmt = \$this->DB->prepare(\$query);\n

EOT;

  

  foreach ($fields as $key => $field) {
    $str .= <<<EOT
    if (\$this->_$key != \$this->_{$key}Old) {
      \$stmt->Parameters->add(\$this->_$key);
    } \n\n
EOT;
  }
  
  $str .= <<<EOT
    \$stmt->ExecuteNonQuery();


EOT;

  foreach ($fields as $key => $field) {
    $str .= '    $this->_'.$key.'Old = $this->'.$key.";\n";
  }
  $str.= <<<EOT

  } catch(DBException \$ex)  {
      echo \$ex->getMessage();
  }
EOT;
  $str .= ' '."\n\n}\n";

  fwrite($file, $str);
  
  fwrite($file, "\n}\n\n?>");
  fclose($file);
  
}
} catch (DBException $ex)   {
  echo $ex->getMessage();
}
?>
